﻿namespace MineSweeping.AppCode
{
    using System;

    public static class MineMatrix
    {
        private const int MineFlag = 9;

        public static int[,] InitMines(int MinesCount, int RowCount, int ColumnCount)
        {
            if (MinesCount >= RowCount * ColumnCount)
            {
                throw new Exception("地雷数必须小于棋盘数");
            }

            var Matrix = new int[RowCount + 2, ColumnCount + 2];

            for (var i = 0; i < MinesCount; i++)
            {
                SetMine(Matrix, RowCount, ColumnCount);
            }

            return Matrix;
        }

        private static void SetMine(int[,] Matrix, int RowCount, int ColumnCount)
        {
            var random = new Random();

            int r;
            int c;

            do
            {
                r = random.Next(1, RowCount + 1);
                c = random.Next(1, ColumnCount + 1);

            } while (Matrix[r, c] == MineFlag);

            Matrix[r, c] = MineFlag;

            int row;
            int col;

            int leftUpValue = GetValue(out row, out col, r, c, Direction.LeftUp, Matrix);
            if (leftUpValue != MineFlag) Matrix[row, col] = leftUpValue + 1;

            int upValue = GetValue(out row, out col, r, c, Direction.Up, Matrix);
            if (upValue != MineFlag) Matrix[row, col] = upValue + 1;

            int rightUp = GetValue(out row, out col, r, c, Direction.RightUp, Matrix);
            if (rightUp != MineFlag) Matrix[row, col] = rightUp + 1;

            int leftValue = GetValue(out row, out col, r, c, Direction.Left, Matrix);
            if (leftValue != MineFlag) Matrix[row, col] = leftValue + 1;

            int rightValue = GetValue(out row, out col, r, c, Direction.Right, Matrix);
            if (rightValue != MineFlag) Matrix[row, col] = rightValue + 1;

            int leftBottomValue = GetValue(out row, out col, r, c, Direction.LeftBottom, Matrix);
            if (leftBottomValue != MineFlag) Matrix[row, col] = leftBottomValue + 1;

            int bottomValue = GetValue(out row, out col, r, c, Direction.Bottom, Matrix);
            if (bottomValue != MineFlag) Matrix[row, col] = bottomValue + 1;

            int rightBottomValue = GetValue(out row, out col, r, c, Direction.RightBottom, Matrix);
            if (rightBottomValue != MineFlag) Matrix[row, col] = rightBottomValue + 1;
        }

        public static int GetValue(out int row, out int col, int r, int c, Direction direction, int[,] Matrix)
        {
            row = 0;
            col = 0;

            switch (direction)
            {
                case Direction.LeftUp:
                    row = r - 1;
                    col = c - 1;
                    break;
                case Direction.Up:
                    row = r - 1;
                    col = c;
                    break;
                case Direction.RightUp:
                    row = r - 1;
                    col = c + 1;
                    break;
                case Direction.Left:
                    row = r;
                    col = c - 1;
                    break;
                case Direction.Right:
                    row = r;
                    col = c + 1;
                    break;
                case Direction.LeftBottom:
                    row = r + 1;
                    col = c - 1;
                    break;
                case Direction.Bottom:
                    row = r + 1;
                    col = c;
                    break;
                case Direction.RightBottom:
                    row = r + 1;
                    col = c + 1;
                    break;
            }

            return Matrix[row, col];
        }
    }
}
